﻿namespace _3_C_运算符;

/// <summary>
///     5_new运算符专属使用
/// </summary>
internal class Being
{
    public Being()
    {
        Console.WriteLine("Being created");
    }
}

internal class TestClass
{
    public TestClass(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    private string name { get; }
    private int age { get; set; }

    public string TestMethod()
    {
        return name;
    }
}

internal class Base
{
}

internal class Derived : Base
{
}

internal class Program
{
    private static void Main(string[] args)
    {
        #region 1_加减乘除运算符

        //// 值的结果类型将会根据操作数最宽的那个类型决定
        //int a = 5 / 2;
        //Console.WriteLine(a);
        //float b = 5 / 2;
        //float d = 5 / 2.0f;
        //double c = 5 / 2.0;
        //Console.WriteLine(b); // 2
        //Console.WriteLine(d); // 2.5
        //Console.WriteLine(c); // 2.5

        #endregion

        #region 2_布尔运算符

        // &&和||都先看第一个参数, 如果第一个参数不满足, 那么再判断第二个参数
        //bool a = true && false;
        //Console.WriteLine(a); // false
        //bool b = true || false;
        //Console.WriteLine(b); // true
        //bool c = !true;
        //Console.WriteLine(c); // false

        #endregion

        #region 3_按位运算符

        //int a = 5;
        //int b = 6;
        //int c = a & b; // 按位与  0101 & 0110 = 0100 -> 4
        //Console.WriteLine(c); // 4
        //int d = a | b; // 按位或 0101 | 0110 = 0111 -> 7
        //Console.WriteLine(d); // 7
        //int e = a ^ b; // 按位异或(不同的直接加) 0101 ^ 0110 = 0011 -> 3
        //Console.WriteLine(e); // 3
        //int f = ~a; // 按位取反 ~0101 1010 -6
        //Console.WriteLine(f); // -2

        #endregion

        #region 4_移位运算符,左移的话不会删除原来的数据, 仅改变每个值的权重, 而右移的话, 可能会删除掉原来的数据, 同样也会改变权重值

        //int a = 5; 0101
        //int b = a << 2; // 左移2位, 如果有空缺则右边补零
        //Console.WriteLine(b); // 20 010100 , 2的4次方 + 2的平方 = 20
        //int c = a >> 2; // 右移2位, 左边有空缺则左边补零, 右边被移出, 也就是0001
        //Console.WriteLine(c); // 1

        #endregion

        #region 5_new运算符

        //var b = new Being();
        //Console.WriteLine(b);
        //var vals = new int[] {1,2,3,4,5};
        //Console.WriteLine(vals); // 指挥返回该对象所对应的类型
        //Console.WriteLine(string.Join("-", vals)); // 对其中的数据进行处理

        #endregion

        #region 6_访问运算符

        //var vals = new int[] { 1, 2, 3, 4, 5 };
        //Console.WriteLine(vals[0]);
        //var domains = new Dictionary<string, string>()
        //{
        //    {"de", "Germany" },
        //    {"us", "United States" },
        //    {"uk", "United Kingdom" }
        //};
        //Console.WriteLine(domains["de"]);
        //oldMethod();

        #endregion

        #region 7_索引的最终运算符: ^: 就是异或符号的标志

        //// 结束运算符^的索引指示从序列结尾开始的元素位置。
        //// 例如，^1指向序列的最后一个元素，^n指向偏移为length - n的元素。
        //int[] vals = {1,2, 3,4,5,6,7};
        //Console.WriteLine(vals[^1]); 
        //Console.WriteLine(vals[^2]);
        //var word = "gray falcon";
        //Console.WriteLine(word[^1]);

        #endregion

        #region 8_范围运算符..(左闭右开)

        //int[] vals = {1,2, 3,4,5,6,7};
        //var slice1 = vals[..3]; // 1,2,3
        //Console.WriteLine(slice1);
        //Console.WriteLine(string.Join("-", vals));
        //Console.WriteLine(string.Join("-", slice1));

        //var slice2 = vals[2..5];
        //var slice3 = vals[..];
        //var slice4 = vals[5..]; 
        //var slice5 = vals[..^0];
        //Console.WriteLine(string.Join("-", slice2));
        //Console.WriteLine(string.Join("-", slice3));
        //Console.WriteLine(string.Join("-", slice4));
        //Console.WriteLine(string.Join("-", slice5));

        #endregion

        #region 9_类型信息 sizeof typeof

        //Console.WriteLine(sizeof(int));
        //Console.WriteLine(sizeof(float));
        //Console.WriteLine(sizeof(Int32));

        //Console.WriteLine(typeof(int));
        //Console.WriteLine(typeof(float));

        //Base _base = new Base();
        //Derived derived = new Derived();
        //Console.WriteLine(derived is Base); // True
        //Console.WriteLine(derived is Derived); // True
        //Console.WriteLine(derived is Object); // True
        //Console.WriteLine(_base is Object); // True
        //Console.WriteLine(_base is Base); // True
        //Console.WriteLine(_base is Derived); // False


        //object[] objects = new object[6];
        //objects[0] = new Base();
        //objects[1] = new Derived();
        //objects[2] = "ZetCode";
        //objects[3] = 12;
        //objects[4] = 1.4;
        //objects[5] = null;

        //for (int i = 0; i < objects.Length; i++)
        //{
        //    // 与强制转换不同, as操作符会返回null, 但是强制转换会抛出异常
        //    string s = objects[i] as string;
        //    Console.Write("{0}:", i);

        //    if (s != null)
        //    {
        //        Console.WriteLine(s);
        //    }
        //    else
        //    {
        //        Console.WriteLine("not a string");
        //    }
        //}

        #endregion

        #region 10_空条件运算符

        //int?[] vals = { 1, 2, 3, null, 4, 5 };

        //int i = 0;

        //while (i < vals.Length)
        //{
        //    // ?运算符防止System.NullReferenceException异常
        //    Console.WriteLine(vals[i]?.GetType());
        //    i++;
        //}

        #endregion

        #region 11_空值运算符

        //// 如果x或y为null, 则使用??运算符返回-1
        //int? x = null;
        //int? y = null;
        //int z = x ?? y ?? -1;
        //Console.WriteLine(z);
        //#endregion

        //#region 12_空折叠赋值运算符
        //List<int> list = new List<int>();
        //list ??= new List<int>() { 1, 2, 3, 4, 5, 6 };
        //list.Add(7);
        //list.Add(8);
        //list.Add(9);

        //Console.WriteLine(string.Join(", ", list));

        //list ??= new List<int>() { 1, 2, 3, 4, 5, 6 };

        //Console.WriteLine(string.Join(", ", list));

        #endregion

        #region 12_Lambda表达式, 和Java很像

        var list = new List<int> { 3, 2, 1, 8, 6, 4, 7, 9, 5 };

        var subList = list.FindAll(val => val > 3);
        var nums2 = list.FindAll(delegate(int i)
        {
            // 匿名委托
            return i <= 3;
        });
        nums2.ForEach(item => { Console.WriteLine(item); });

        foreach (var i in subList) Console.WriteLine(i);

        #endregion

        #region 13_?和is not

        #endregion
    }


    // 在进行调用时会显示已过时, 但是不会阻止编译器编译
    [Obsolete("这是一个已经过时的方法, 请使用新方法newMethod!", false)]
    public static void oldMethod()
    {
        Console.WriteLine("oldMethod");
    }

    public static void newMethod()
    {
        Console.WriteLine("newMethod");
    }
}